//
//  ViewController.m
//  testSocketServer
//
//  Created by eq2016 on 2019/4/30.
//  Copyright © 2019年 eq2017. All rights reserved.
//

#import "ViewController.h"
#import "GCDAsyncSocket.h"
#import "SVProgressHUD.h"
#import <AVKit/AVKit.h>
#import <AVFoundation/AVFoundation.h>
@interface ViewController ()<GCDAsyncSocketDelegate>{

}

@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UILabel *conStatus;
@property (weak, nonatomic) IBOutlet UILabel *transNumber;
@property (strong, nonatomic)GCDAsyncSocket *serverScoket;
@property (copy, nonatomic)NSMutableArray *clientSockets;
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *statusButton;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@property (copy, nonatomic)NSDictionary *headerDict;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //初始化客户端数组
    _clientSockets = [NSMutableArray array];
    //初始化服务器socket
    self.serverScoket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    self.transNumber.text = [NSString stringWithFormat:@"连接数: %lu",(unsigned long)self.clientSockets.count];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];
}
//开启服务器
-(void)startServer {
    NSError *error = nil;
    BOOL result = [self.serverScoket acceptOnPort:6677 error:&error];
    if (result) {
        NSLog(@"服务器启动成功.");
    }else {
        NSLog(@"服务器启动失败.");
    }
}

//关闭服务器
- (void)disconnectServer {

    if (!self.serverScoket.isConnected) {
        [self.serverScoket disconnectAfterReading];
        //关闭服务器清除所有的客户端scoket对象
        [self.clientSockets removeAllObjects];
    }
}


//开启服务器或者关闭服务器
- (IBAction)startOrDisConnectClick:(UIButton *)btn{
    if (!btn.isSelected) {
        [self startServer];
        btn.selected = YES;
    }else {
        [self disconnectServer];
        btn.selected = NO;
    }
    
}
//向每个客户端发送数据
- (IBAction)sendClick:(UIButton *)sender {
    if (self.clientSockets == nil)return;
    NSData *data = [self.textField.text dataUsingEncoding:NSUTF8StringEncoding];
    NSData *senData = [self sendData:data type:@"text" Info:@"B"];
    [self.clientSockets enumerateObjectsUsingBlock:^(GCDAsyncSocket *sock, NSUInteger idx, BOOL * _Nonnull stop) {

        [sock writeData:senData withTimeout:-1 tag:0];
    }];
    NSLog(@"文件长度--%ld",senData.length);
    self.textField.text = @"";
}
- (IBAction)imageClick:(id)sender {
    NSData *imageData = UIImagePNGRepresentation(self.imageView.image);
    NSData *senData = [self sendData:imageData type:@"iamge" Info:@"111.png"];
    [self.clientSockets enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj writeData:senData withTimeout:-1 tag:0];
    }];
    NSLog(@"文件长度--%ld",senData.length);
    
}


//数据粘包
- (NSData *)sendData:(NSData *)data type:(NSString *)typeStr Info:(NSString *)info {
    NSMutableDictionary *headerDict = [NSMutableDictionary dictionary];
    [headerDict setObject:typeStr forKey:@"type"];
    [headerDict setObject:info forKey:@"info"];
    [headerDict setObject:[NSString stringWithFormat:@"%ld",data.length] forKey:@"length"];
    NSMutableData *sendData = [NSMutableData data];
    NSData *headerData = [NSJSONSerialization dataWithJSONObject:headerDict options:NSJSONWritingPrettyPrinted error:nil];
    [sendData appendData:headerData];
    [sendData appendData:[GCDAsyncSocket CRLFData]];
    [sendData appendData:data];

    return sendData;
}


#pragma make --GCDAsyncSocketDelegate
    

//连接成功
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
    [self.clientSockets addObject:newSocket];
    self.transNumber.text = [NSString stringWithFormat:@"连接数: %lu",(unsigned long)self.clientSockets.count];
    NSLog(@"连接成功");
    NSLog(@"客户端地址:%@....端口%d",newSocket.connectedHost,newSocket.connectedPort);

    //一次请求一次接收,数据过大会自动进行拆包
//    [newSocket readDataWithTimeout:-1 tag:0];
    //一个请求可进行多次接收,以分界符为界
    [newSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
    self.conStatus.text = @"已连接";
}

//读取进度
- (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
//    NSLog(@"读取部分长度%lu",partialLength);
    float progress = [sock progressOfReadReturningTag:&tag bytesDone:nil total:nil];
    if (progress > 0.01 && progress < 0.99) {
        [SVProgressHUD showProgress:progress];
    }else {
        [SVProgressHUD dismiss];
    }
}

//读取数据
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {

    NSLog(@"%s",__FUNCTION__);
    NSLog(@"总长度--%ld",data.length);
    //解析头文件
    if (!_headerDict) {
        _headerDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"传输头--%@",_headerDict);
        if (!_headerDict) {
            NSLog(@"errer: 无头文件");
            [self replyClientSocket:sock Text:@"没有遵守协议" Info:@"2" Tag:tag];
            return;
        }
        NSString *lengthStr = _headerDict[@"length"];
        //读取数据的长度
        [sock readDataToLength:lengthStr.integerValue withTimeout:-1 tag:tag];
        return;
    }
    //判断接受的数据长度是否与头文件的一致
    NSString *lengthStr = _headerDict[@"length"];
    if (data.length != lengthStr.integerValue) {
        NSLog(@"文件错误");
        [self replyClientSocket:sock Text:@"文件接收错误" Info:@"1" Tag:tag];
        return;
    }
    NSString *type = _headerDict[@"type"];
    if ([type isEqualToString:@"longConnect"]){
        self.conStatus.text = @"已连接";
        NSLog(@"l连接正常");
    }else if ([type isEqualToString:@"image"]) {
        [self replyClientSocket:sock Text:@"已收到" Info:@"0" Tag:tag];
        UIImage *image = [UIImage imageWithData:data];
        self.imageView.image = image;
        NSLog(@"图片二进制长度--%ld",data.length);
    }else if ([type isEqualToString:@"text"]) {
        NSString *info = _headerDict[@"info"];
        NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSString *texts = [NSString stringWithFormat:@"%@\n %@:%@", self.textView.text, info, text];
        NSLog(@"接收到的数据%@",text);
        self.textView.text = texts;
    }else if ([type isEqualToString:@"mp4"]){
        [self replyClientSocket:sock Text:@"已收到" Info:@"0" Tag:tag];
        [SVProgressHUD showSuccessWithStatus:@"接收完成"];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //存放在桌面 再播放视频
            [data writeToFile:@"/Users/eq2016/Desktop/aaaaa.mp4" atomically:YES];
            [self playerURL:[NSURL fileURLWithPath:@"/Users/eq2016/Desktop/aaaaa.mp4"]];
        });
        
    }
    
    [sock readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:tag];
    self.headerDict = nil;

}
//收到数据后,回应客户端
- (void)replyClientSocket:(GCDAsyncSocket *)socket Text:(NSString *)text Info:(NSString *)info Tag:(long)tag {
    NSData *senData = [self sendData:[text dataUsingEncoding:NSUTF8StringEncoding] type:@"reply" Info:info];
    [socket writeData:senData withTimeout:-1 tag:tag];
}

//连接断开
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
    NSLog(@"断开连接,断开原因: %@",err);
    
    self.conStatus.text = @"已断开";
    
    [self.clientSockets removeObject:sock];
    self.transNumber.text = [NSString stringWithFormat:@"连接数: %lu",(unsigned long)self.clientSockets.count];
    self.imageView.image = nil;
    self.headerDict = nil;
}

//播放视频
- (void)playerURL:(NSURL *)url {
    AVPlayerViewController *playerVC = [[AVPlayerViewController alloc] init];
    playerVC.player = [AVPlayer playerWithURL:url];
    [playerVC.player play];
    [self presentViewController:playerVC animated:YES completion:nil];
}

//获取当前时间戳  （以毫秒为单位）
- (NSString *)getNowTimeTimestamp3{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss SSS"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    //设置时区,这个对于时间的处理有时很重要
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    [formatter setTimeZone:timeZone];
    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]*1000];
    return timeSp;
    
}

@end











